package com.fone.player.storage.download;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.database.sqlite.SQLiteDatabase;

import com.fone.player.entity.OfflineCache;
import com.fone.player.entity.OfflineCacheFragment;
import com.fone.player.storage.OfflineCacheFileDataBaseAdapter;
import com.fone.player.storage.OfflineCacheFolderDataBaseAdapter;
import com.fone.player.storage.OfflineCacheFragmentDataBaseAdapter;
import com.fone.player.util.L;
import com.fone.player.util.SystemUtil;

public class SaveCacheDataUtil {
	public static final String TAG = SaveCacheDataUtil.class.getSimpleName();
	public static final String DOWNLOAD_FILE_NAME = "new_download_info";
	private static final SaveCacheDataUtil mInstance = new SaveCacheDataUtil();

	public static SaveCacheDataUtil getInstance() {
		return mInstance;
	}

	/**
	 * 
	 * 根据where条件删除对应缓存的json文件
	 * 
	 * @param where
	 *            查询条件
	 * @return void
	 */
	public static void deleteCacheJSONFile(List<OfflineCache> offlineCacheList) {

		String offlineCachePath = SystemUtil.getInstance()
				.getOfflineCachePath();

		// 开始删除
		for (OfflineCache offlineCache : offlineCacheList) {
			if (offlineCache == null) {
				L.v(TAG, "deleteCacheJSONFile", "offlineCache=null");
				continue;
			}

			if (offlineCache.getCacheStoragePath() == null
					|| ("".equals(offlineCache.getCacheStoragePath()))) {
				offlineCache.setCacheStoragePath(offlineCachePath);
			}
			String path = offlineCache.getCacheStoragePath() + File.separator
					+ offlineCache.getCacheName()
					+ offlineCache.getCacheEpisodeNum()
					+ offlineCache.getCacheCID();
			L.v(TAG,
					"deleteCacheJSONFile",
					"start path=" + path + " isExist="
							+ new File(path).exists() + " cid="
							+ offlineCache.getCacheCID() + " name="
							+ offlineCache.getCacheName()
							+ offlineCache.getCacheEpisodeNum());

			DownloadUtil.deleteDirectory(path);

			L.v(TAG,
					"deleteCacheJSONFile",
					"end path=" + path + " isExist=" + new File(path).exists()
							+ " cid=" + offlineCache.getCacheCID() + " name="
							+ offlineCache.getCacheName()
							+ offlineCache.getCacheEpisodeNum());

		}

	}

	public void initOfflineCacheDatabase(SQLiteDatabase sqliteDatabase) {

		ArrayList<OfflineCacheFragment> offlineCacheFragmentList = new ArrayList<OfflineCacheFragment>();
		ArrayList<OfflineCache> offlineCacheList = getOfflineCacheListByJSON(SystemUtil
				.getInstance().getOfflineCachePath());
		L.v(TAG, "initOfflineCacheDatabase", "offlineCacheList.size()="
				+ offlineCacheList.size());
		for (OfflineCache offlineCache : offlineCacheList) {
			if (offlineCache != null) {
				L.v(TAG, "initCacheDB",
						"offlineCache.getOfflineCacheFragmentList().size()="
								+ offlineCache.getOfflineCacheFragmentList()
										.size());
				if (offlineCache.getOfflineCacheFragmentList().size() != 0) {
					for (OfflineCacheFragment offlineCacheFragment : offlineCache
							.getOfflineCacheFragmentList()) {
						if (offlineCacheFragment != null) {
							offlineCacheFragmentList.add(offlineCacheFragment);
						}
					}
				}

			}
		}

		// 插入文件列表
		OfflineCacheFolderDataBaseAdapter.getInstance().addOfflineCacheFolder(
				sqliteDatabase, offlineCacheList);

		// 插入文件列表
		OfflineCacheFileDataBaseAdapter.getInstance().addOfflineCacheFileList(
				sqliteDatabase, offlineCacheList);

		// 插入分片列表
		OfflineCacheFragmentDataBaseAdapter.getInstance()
				.addOfflineCacheFragmentList(sqliteDatabase,
						offlineCacheFragmentList);

	}

	/**
	 * 
	 * 保存json
	 * 
	 * @param isDownloaded
	 *            缓存是否完成
	 * @return void
	 */
	public void saveCacheJSONFile(OfflineCache offlineCache) {

		// long startJsonTime = System.currentTimeMillis();

		if (offlineCache != null) {

			getFilePathByOfflineCache(offlineCache);

		}

		// long endJsonTime = System.currentTimeMillis();
		// L.v(TAG, "saveCacheJSONFile", "start save JSON use time="
		// + (endJsonTime - startJsonTime) + "ms");
	}

	private ArrayList<OfflineCache> getOfflineCacheListByJSON(String folderPath) {
		ArrayList<OfflineCache> offlineCacheList = new ArrayList<OfflineCache>();
		File files = new File(folderPath);
		if (!files.exists()) {
			return offlineCacheList;
		}

		String[] file = files.list();
		if (file == null) {
			L.e(TAG, "getOfflineCacheListByJSON", "file=null");
			return offlineCacheList;
		}

		for (String folderName : file) {

			try {
				File newFile = new File(folderPath + File.separator
						+ folderName + File.separator + DOWNLOAD_FILE_NAME);

				if (newFile.exists() && newFile.length() != 0) {
					BufferedReader br = new BufferedReader(new FileReader(
							newFile));
					StringBuffer sb = new StringBuffer();
					String line = br.readLine();
					while (line != null) {
						sb.append(line);
						line = br.readLine();
					}

					br.close();

					if (!sb.toString().trim().equals("")
							|| sb.toString() != null) {
						OfflineCache offlineCache = getOfflineCacheByJson(sb
								.toString());

						if (offlineCache != null) {
							offlineCacheList.add(offlineCache);
						}
					}
				}
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return offlineCacheList;
	}

	public ArrayList<OfflineCacheFragment> getOfflineCacheFragmentListByFilePath(
			String folderPath) {

		File file = new File(folderPath + File.separator + DOWNLOAD_FILE_NAME);
		if (!file.exists()) {
			L.e(TAG, "getOfflineCacheFragmentListByJSON",
					"no exists jsonFilePath=" + file.getAbsolutePath());
			return null;
		}
		ArrayList<OfflineCacheFragment> offlineCacheFragmentList = null;
		try {
			BufferedReader br = new BufferedReader(new FileReader(file));
			StringBuffer sb = new StringBuffer();
			String line = br.readLine();
			while (line != null) {
				sb.append(line);
				line = br.readLine();
			}

			br.close();

			if (!sb.toString().trim().equals("") || sb.toString() != null) {
				offlineCacheFragmentList = getOfflineCacheFragmentListByJson(sb
						.toString());
			} else {
				L.e(TAG, "getOfflineCacheFragmentListByJSON",
						"empty content jsonFilePath=" + file.getAbsolutePath());
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return offlineCacheFragmentList;
	}

	/**
	 * 获取json数据
	 */
	public void getFilePathByOfflineCacheProgress(OfflineCache offlineCache) {

		OfflineCache offlineCacheTemp = new OfflineCache();
		offlineCacheTemp = offlineCache;
		getFilePathByOfflineCache(offlineCacheTemp);
		offlineCache
				.setCacheAlreadySize(offlineCacheTemp.getCacheAlreadySize());
		offlineCache.setCacheTotalSize(offlineCacheTemp.getCacheTotalSize());
	}

	/**
	 * 获取json数据
	 */
	private void getFilePathByOfflineCache(OfflineCache offlineCache) {
		if (offlineCache == null) {
			L.e(TAG, "getFilePathByOfflineCache", "offlineCache=null");
			return;
		}

		try {
			String json = getJsonByOfflineCache(offlineCache);
			String folderPath = offlineCache.getCacheStoragePath();
			File parentFolder = new File(folderPath);
			if (!parentFolder.exists()) {
				parentFolder.mkdirs();
			}
			String filePath = parentFolder.getAbsolutePath() + File.separator
					+ DOWNLOAD_FILE_NAME;
			File newFile = new File(filePath);
			if (!newFile.exists()) {
				L.e(TAG, "getFilePathByOfflineCache", "filePath=" + filePath
						+ " exists=" + new File(filePath).exists());
				newFile.createNewFile();
			}
			FileWriter fw = new FileWriter(newFile, false);
			BufferedWriter bw = new BufferedWriter(fw);
			bw.write(json);

			bw.flush();
			bw.close();
			fw.close();

		} catch (FileNotFoundException e) {
			if (e != null) {
				e.printStackTrace();
				L.e(TAG, "saveCacheJSONFile",
						"FileNotFoundException=" + e.getMessage());
			}

		} catch (IOException e) {
			if (e != null) {
				e.printStackTrace();
				L.e(TAG, "saveCacheJSONFile", "IOException=" + e.getMessage());
			}

		} catch (Exception e) {
			if (e != null) {
				e.printStackTrace();
				L.e(TAG, "saveCacheJSONFile", "Exception=" + e.getMessage());
			}

		}
	}

	public String getJsonByOfflineCache(OfflineCache offlineCache) {
		JSONObject fileJsonObj = new JSONObject();
		try {
			fileJsonObj.put("video_id", offlineCache.getCacheVideoId());
			fileJsonObj.put("cid", offlineCache.getCacheCID());
			fileJsonObj.put("ccid", offlineCache.getCacheCCID());
			fileJsonObj.put("name", offlineCache.getCacheName());
			fileJsonObj.put("content_type", offlineCache.getCacheContentType());
			fileJsonObj.put("episode_num", offlineCache.getCacheEpisodeNum());
			fileJsonObj.put("already_size", offlineCache.getCacheAlreadySize());
			fileJsonObj.put("total_size", offlineCache.getCacheTotalSize());
			fileJsonObj.put("download_type",
					offlineCache.getCacheDownloadType());
			fileJsonObj.put("download_state",
					offlineCache.getCacheDownloadState());
			fileJsonObj.put("duration", offlineCache.getCacheDuration());
			fileJsonObj.put("dfnt", offlineCache.getCacheDefinitionType());
			fileJsonObj.put("store_path", offlineCache.getCacheStoragePath());
			fileJsonObj.put("fragment_count",
					offlineCache.getCacheFragmentCount());
			fileJsonObj.put("xyzplay_url", offlineCache.getCacheXYZPlayUrl());
			fileJsonObj.put("image_url", offlineCache.getCacheImageUrl());
			fileJsonObj.put("sort_index", offlineCache.getSortIndex());
			JSONArray fragmentJsonArray = new JSONArray();
			for (OfflineCacheFragment offlineCacheFragment : offlineCache
					.getOfflineCacheFragmentList()) {
				if (offlineCacheFragment == null) {
					L.v(TAG, "getJsonByOfflineCache",
							"offlineCacheFragment=null");
					continue;
				}
				JSONObject fragmentJsonObj = new JSONObject();
				fragmentJsonObj.put("cid", offlineCacheFragment.getCacheCID());
				fragmentJsonObj.put("current_index",
						offlineCacheFragment.getCacheCurrentIndex());
				fragmentJsonObj.put("duration",
						offlineCacheFragment.getCacheDuration());
				fragmentJsonObj.put("already_size",
						offlineCacheFragment.getCacheAlreadySize());
				fragmentJsonObj.put("total_size",
						offlineCacheFragment.getCacheTotalSize());
				fragmentJsonObj.put("dfnt",
						offlineCacheFragment.getCacheDefinitionType());
				fragmentJsonObj.put("download_state",
						offlineCacheFragment.getCacheDownloadState());
				fragmentJsonObj.put("fragment_store_path",
						offlineCacheFragment.getCacheFragmentStoragePath());
				fragmentJsonObj.put("download_url",
						offlineCacheFragment.getCacheFragmentUrl());
				fragmentJsonArray.put(fragmentJsonObj);
			}

			fileJsonObj.put("fragment_list", fragmentJsonArray);
		} catch (JSONException e) {
			L.e(TAG, "getJsonByOfflineCache", "JSONException=" + e.getMessage());
			e.printStackTrace();

		}
		return fileJsonObj.toString();
	}

	private static OfflineCache getOfflineCacheByJson(String json) {
		OfflineCache offlineCache = new OfflineCache();
		try {
			JSONObject jsonObject = new JSONObject(json);
			offlineCache.setCacheCID(jsonObject.optLong("cid"));
			offlineCache.setCacheCCID(jsonObject.optLong("ccid"));
			offlineCache.setCacheVideoId(jsonObject.optLong("video_id"));
			offlineCache.setCacheDownloadState(jsonObject
					.optInt("download_state"));
			offlineCache.setCacheImageUrl(jsonObject.optString("image_url"));
			offlineCache
					.setCacheXYZPlayUrl(jsonObject.optString("xyzplay_url"));
			if (jsonObject.optString("store_path") != null
					&& !jsonObject.optString("store_path").equals("")) {
				offlineCache.setCacheStoragePath(jsonObject
						.optString("store_path"));
			} else {
				if ("".equals(offlineCache.getCacheStoragePath())) {
					L.e(TAG, "getOfflineCacheByJson", "storagePath=null");
					return null;
				}
			}

			if (jsonObject.optString("name") != null
					&& !jsonObject.optString("name").equals("")) {
				offlineCache.setCacheName(jsonObject.optString("name"));
			} else {
				if ("".equals(offlineCache.getCacheName())) {
					L.e(TAG, "getOfflineCacheByJson", "name=null");
					return null;
				}
			}

			offlineCache
					.setCacheEpisodeNum(jsonObject.optString("episode_num"));
			offlineCache.setCacheImageUrl(jsonObject.optString("image_url"));
			offlineCache
					.setCacheAlreadySize(jsonObject.optLong("already_size"));
			offlineCache.setCacheTotalSize(jsonObject.getLong("total_size"));
			offlineCache.setCacheDownloadType(jsonObject
					.optInt("download_type"));
			offlineCache.setCacheContentType(jsonObject.optInt("content_type"));
			// new add
			offlineCache.setCacheDefinitionType(jsonObject.optInt("dfnt"));
			offlineCache.setCacheDuration(jsonObject.optLong("duration"));
			offlineCache.setCacheFragmentCount(jsonObject
					.optInt("fragment_count"));
			offlineCache.setSortIndex(jsonObject.optInt("sort_index"));
			ArrayList<OfflineCacheFragment> offlineCacheFragmentList = new ArrayList<OfflineCacheFragment>();
			JSONArray fragmentArray = jsonObject.optJSONArray("fragment_list");
			if (fragmentArray != null) {
				for (int i = 0; i < fragmentArray.length(); i++) {
					OfflineCacheFragment offlineCacheFragment = new OfflineCacheFragment();
					JSONObject unitObject = (JSONObject) fragmentArray.get(i);

					// 新版本
					offlineCacheFragment.setCacheDownloadState(unitObject
							.optInt("download_state"));
					offlineCacheFragment.setCacheFragmentUrlMD5(unitObject
							.optString("url_md5"));
					offlineCacheFragment.setCacheFragmentUrl(unitObject
							.optString("download_url"));
					offlineCacheFragment.setCacheFragmentStoragePath(unitObject
							.optString("fragment_store_path"));
					offlineCacheFragment.setCacheCurrentIndex(unitObject
							.optInt("current_index"));
					offlineCacheFragment.setCacheDuration(unitObject
							.optLong("duration"));
					offlineCacheFragment.setCacheCID(unitObject.optLong("cid"));
					offlineCacheFragment.setCacheAlreadySize(unitObject
							.optLong("already_size"));
					offlineCacheFragment.setCacheDefinitionType(unitObject
							.optInt("dfnt"));
					offlineCacheFragment.setCacheTotalSize(unitObject
							.optLong("total_size"));
					offlineCacheFragmentList.add(offlineCacheFragment);
				}
			} else {
				L.e(TAG, "getOfflineCacheByJson", "fragmentArray=null");
			}
			offlineCache.setOfflineCacheFragmentList(offlineCacheFragmentList);
		} catch (JSONException e) {
			e.printStackTrace();
		}

		return offlineCache;
	}

	private ArrayList<OfflineCacheFragment> getOfflineCacheFragmentListByJson(
			String json) {
		L.v(TAG, "getOfflineCacheFragmentListByJson", "start");
		ArrayList<OfflineCacheFragment> offlineCacheFragmentList = null;

		try {

			JSONObject jsonObject = new JSONObject(json);

			JSONArray fragmentArray = jsonObject.optJSONArray("fragment_list");

			if (fragmentArray != null && fragmentArray.length() > 0) {

				offlineCacheFragmentList = new ArrayList<OfflineCacheFragment>();

				for (int i = 0; i < fragmentArray.length(); i++) {

					OfflineCacheFragment offlineCacheFragment = new OfflineCacheFragment();
					JSONObject unitObject = (JSONObject) fragmentArray.get(i);

					// 新版本
					offlineCacheFragment.setCacheDownloadState(unitObject
							.optInt("download_state"));
					offlineCacheFragment.setCacheFragmentUrlMD5(unitObject
							.optString("url_md5"));
					offlineCacheFragment.setCacheFragmentUrl(unitObject
							.optString("download_url"));
					offlineCacheFragment.setCacheFragmentStoragePath(unitObject
							.optString("fragment_store_path"));
					offlineCacheFragment.setCacheCurrentIndex(unitObject
							.optInt("current_index"));
					offlineCacheFragment.setCacheDuration(unitObject
							.optLong("duration"));
					offlineCacheFragment.setCacheCID(unitObject.optLong("cid"));
					offlineCacheFragment.setCacheAlreadySize(unitObject
							.optLong("already_size"));
					offlineCacheFragment.setCacheDefinitionType(unitObject
							.optInt("dfnt"));
					offlineCacheFragment.setCacheTotalSize(unitObject
							.optLong("total_size"));
					offlineCacheFragmentList.add(offlineCacheFragment);
				}
			} else {
				L.e(TAG, "getOfflineCacheFragmentListByJson",
						"fragmentArray=null");
			}
		} catch (JSONException e) {
			e.printStackTrace();
		}

		return offlineCacheFragmentList;
	}
}
